#include "./PORT/port.h"
#include "../System/config.h"
#include "./BSP/KEY/gpio_key.h"
#include "./BSP/KEY/key.h"

#if CFG_GPIO_KEY_EN == 1

const uint8_t gpio_key_pin[] = {CFG_GPIO_KEY_PIN};
const uint8_t gpio_key_value[] = {CFG_GPIO_KEY_VALUE};
const uint8_t gpio_key_polarity[] = {CFG_GPIO_KEY_POLARITY};

static key_state_t key_state = {
    .event = KEY_EVENT_NONE, // 初始状态为用户自定义事件
    .key_value = NO_KEY      // 初始按键值为无按键
};

/**
 * @breif   初始化按键GPIO
 * @param   无
 * @retval  无
 */
void gpio_key_init(void)
{
    for (uint8_t i = 0; i < sizeof(gpio_key_pin); i++)
    {
        if (gpio_key_polarity[i] == 0)
            gpio_pin_init(gpio_key_pin[i],
                          GPIO_MODE_IN, GPIO_OTYPE_PP, GPIO_SPEED_LOW, GPIO_PUPD_PU); /* LED_R引脚模式设置 */
        else
            gpio_pin_init(gpio_key_pin[i],
                          GPIO_MODE_IN, GPIO_OTYPE_PP, GPIO_SPEED_LOW, GPIO_PUPD_PD); /* LED_R引脚模式设置 */
    }
}

/**
 * @breif   读取按键GPIO状态
 * @param   无
 * @retval  按键值
 */
uint8_t gpio_key_read(void)
{
    for (uint8_t i = 0; i < sizeof(gpio_key_pin); i++)
    {
        if (gpio_read_pin(gpio_key_pin[i]) == gpio_key_polarity[i])
            return gpio_key_value[i];
    }
    return NO_KEY;
}

/**
 * @breif   获取gpio按键值
 * @param   state 按键状态结构体指针
 * @retval  按键值
 */
void gpio_key_get_state(key_state_t *state)
{
    state->event = key_state.event;
    state->key_value = key_state.key_value;
    key_state.event = KEY_EVENT_NONE; // 重置事件为用户自定义
    key_state.key_value = NO_KEY;     // 重置按键值为无按
}

/**
 * @breif   gpio按键扫描
 * @param   无
 * @retval  无
 */
void gpio_key_scan(void)
{
    static uint8_t last_key = NO_KEY;     // 上次扫描的按键值
    static uint8_t debounce_count = 0;    // 消抖计数器
    static uint16_t press_duration = 0;    // 按键持续按下时间
    static uint8_t click_count = 0;       // 连击计数
    static uint8_t pending_key = NO_KEY;  // 等待处理的按键值
    static uint8_t multi_click_timer = 0; // 多击超时计时器

    uint8_t current_key = gpio_key_read(); // 读取当前gpio按键值

    /*--- 按键状态机 ---*/
    // 状态1: 按键值变化 (可能抖动或真实按键)
    if (current_key != last_key)
    {
        debounce_count++;

        // 消抖确认
        if (debounce_count >= DEBOUNCE_THRESHOLD)
        {
            // 按键释放事件
            if (current_key == NO_KEY)
            {
                // 长按后释放
                if (press_duration >= LONG_PRESS_TICKS)
                {
                    key_state.event = KEY_EVENT_UP;
                    key_state.key_value = pending_key;
                    //  这里可以触发KEY_EVENT_UP事件
                }
                // 短按释放 (准备连击检测)
                else
                {
                    click_count++;
                    pending_key = last_key;
                    multi_click_timer = MULTI_CLICK_TIMEOUT; // 启动多击超时计时
                }
                press_duration = 0; // 重置按下计时
            }
            // 新按键按下
            else
            {
                pending_key = current_key;
            }

            last_key = current_key; // 更新确认的按键值
        }
    }
    // 状态2: 按键值稳定
    else
    {
        debounce_count = 0; // 重置消抖计数器

        // 按键持续按下处理
        if (current_key != NO_KEY)
        {
            press_duration++;

            // 长按触发
            if (press_duration == LONG_PRESS_TICKS)
            {
                click_count = 0; // 长按发生时清除连击计数
                key_state.event = KEY_EVENT_LONG_PRESS;
                key_state.key_value = current_key;
            }
            // 长按保持触发
            else if (press_duration >= HOLD_TICKS)
            {
                if ((press_duration % 10) == 0)
                {
                    key_state.event = KEY_EVENT_HOLD;
                    key_state.key_value = current_key;
                }
            }
        }
    }

    /*--- 多击事件检测 ---*/
    if (multi_click_timer > 0)
    {
        multi_click_timer--;

        // 多击超时处理
        if (multi_click_timer == 0)
        {
            if (click_count == 1)
                key_state.event = KEY_EVENT_CLICK;
            else if (click_count == 2)
                key_state.event = KEY_EVENT_DOUBLE_CLICK;
            else if (click_count == 3)
                key_state.event = KEY_EVENT_TRIPLE_CLICK;

            key_state.key_value = pending_key;

            click_count = 0;      // 重置连击计数
            pending_key = NO_KEY; // 清除待处理按键
        }
    }
}

#endif
